package com.yoyo.ad.service;

import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import android.util.SparseIntArray;

import androidx.annotation.Nullable;

import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.yoyo.ad.bean.AdStatisticsBean;
import com.yoyo.ad.confusion.AdLocalSourceRecord;
import com.yoyo.ad.confusion.AdManage;
import com.yoyo.ad.gen.AdStatisticsBeanDao;
import com.yoyo.ad.main.IUpdateView;
import com.yoyo.ad.utils.StringUtil;
import com.yoyo.ad.bean.AdInterceptBean;
import com.yoyo.ad.contract.AdContract;
import com.yoyo.ad.gen.AdInterceptBeanDao;
import com.yoyo.ad.presenter.AdPresenter;
import com.yoyo.ad.utils.GreenDaoManager;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import rx.functions.Action1;
import rx.schedulers.Schedulers;

public class RequestService extends IntentService implements AdContract.View {
    private static final String TAG = "RequestService";
    public static final int FLAG_AD_CONFIG = 0x01;
    public static final int FLAG_CONFINED_REPORT = 0x02;
    public static final int FLAG_STATISTICS_REPORT = 0x03;
    public static final String id = "Request_1";
    public static final String name = "Request_name_1";

    public static void newInstance(Context context, int flag) {
        if (flag == FLAG_CONFINED_REPORT)
            if (AdLocalSourceRecord.canUpload(context)) {
                AdLocalSourceRecord.setUploadTime(context);
            } else {
                //受限上报限制
                return;
            }
        Intent intent = new Intent(context, RequestService.class);
        intent.putExtra("flag", flag);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(intent);
        } else {
            context.startService(intent);
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_HIGH);
            channel.enableLights(false);
            channel.enableVibration(false);
            channel.setVibrationPattern(new long[]{0});
            channel.setSound(null, null);
            ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
            Notification.Builder builder = new Notification.Builder(getApplicationContext(), id);
            startForeground(0x06, builder.build());
        }
    }

    private AdPresenter mAdPresenter;

    public RequestService() {
        super("RequestService");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        int flag = FLAG_AD_CONFIG;
        if (intent != null) {
            flag = intent.getIntExtra("flag", FLAG_AD_CONFIG);
        }
        if (mAdPresenter == null) {
            mAdPresenter = new AdPresenter(this, this);
        }
        switch (flag) {
            case FLAG_AD_CONFIG:
                mAdPresenter.qryAdConfigList();
                break;
            case FLAG_CONFINED_REPORT:
                addBound();
                AdLocalSourceRecord.setUploadTime(this);
                break;
            case FLAG_STATISTICS_REPORT:
                report();
                break;
        }
    }

    private void report() {
        final AdStatisticsBeanDao adStatisticsBeanDao = GreenDaoManager.getInstance().getDaoSession().getAdStatisticsBeanDao();
        long count = adStatisticsBeanDao.count();
        if (count > 0) {
            final List<AdStatisticsBean> list = adStatisticsBeanDao.queryBuilder().orderAsc(AdStatisticsBeanDao.Properties.BoundedTime).limit(10).list();
//            Gson gson = new Gson();
            Gson gson = new GsonBuilder().setExclusionStrategies(
                    new ExclusionStrategy() {
                        @Override
                        public boolean shouldSkipField(FieldAttributes f) {
                            //过滤掉字段名包含"id","address"的字段
                            return f.getName().equals("id");
                        }

                        @Override
                        public boolean shouldSkipClass(Class<?> clazz) {
                            // 过滤掉 类名包含 Bean的类
                            return false;
                        }
                    }).create();
            String s = gson.toJson(list);
            mAdPresenter.addStatistics(s, new IUpdateView() {
                @Override
                public void success() {
                    adStatisticsBeanDao.rx().deleteInTx(list).subscribeOn(Schedulers.io())
                            .subscribe(new Action1<Void>() {
                                @Override
                                public void call(Void aVoid) {
                                    RequestService.newInstance(RequestService.this, FLAG_STATISTICS_REPORT);
                                }
                            });
                }
            });
        }
    }

    private synchronized void addBound() {
        List<AdInterceptBean> list = GreenDaoManager.getInstance().getDaoSession().getAdInterceptBeanDao().queryBuilder().limit(1).list();
        if (list.size() > 0) {
            String boundedTime = list.get(0).getBoundedTime();
            final List<AdInterceptBean> adInterceptBeanList = GreenDaoManager.getInstance().getDaoSession().getAdInterceptBeanDao().queryBuilder()
                    .where(AdInterceptBeanDao.Properties.BoundedTime.eq(boundedTime))
                    .orderAsc(AdInterceptBeanDao.Properties.BoundedTime)
                    .list();

            SparseIntArray adPositionMap = new SparseIntArray();
            Map<String, Integer> adMap = new HashMap<>();

            JSONArray jsonArray = new JSONArray();
            JSONArray adJsonArray = new JSONArray();

            for (AdInterceptBean bean : adInterceptBeanList) {
                if (bean.getBoundedType() == AdManage.INTERCEPT_POSITION) {
                    adPositionMap.put(bean.getAdPositionId(), adPositionMap.get(bean.getAdPositionId(), 0) + 1);
                } else {
                    String key = bean.getAdId() + "_" + bean.getBoundedType();
                    adMap.put(key, StringUtil.optInteger(adMap.get(key), 0) + 1);
                }
            }
            int size = adPositionMap.size();
            for (int i = 0; i < size; i++) {
                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("adPositionConfigId", adPositionMap.keyAt(i));
                    jsonObject.put("boundedCount", adPositionMap.valueAt(i));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                jsonArray.put(jsonObject);
            }

            for (Map.Entry<String, Integer> entry : adMap.entrySet()) {
                String[] key = entry.getKey().split("_");
                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("adId", key[0]);
                    jsonObject.put("boundedType", key[1]);
                    jsonObject.put("boundedCount", entry.getValue());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                adJsonArray.put(jsonObject);
            }
            if (jsonArray.length() > 0 || adJsonArray.length() > 0)
                mAdPresenter.addBounded(true, boundedTime.concat(" 11:12:13"), jsonArray.toString(), adJsonArray.toString(), new IUpdateView() {
                    @Override
                    public void success() {
                        GreenDaoManager.getInstance().getDaoSession().getAdInterceptBeanDao().rx()
                                .deleteInTx(adInterceptBeanList).subscribeOn(Schedulers.io())
                                .subscribe(new Action1<Void>() {
                                    @Override
                                    public void call(Void aVoid) {
                                        RequestService.newInstance(RequestService.this, FLAG_CONFINED_REPORT);
                                    }
                                });
                    }
                });
        }
    }

    @Override
    public void onAdSuccess() {

    }

    @Override
    public void onAdFail(String err) {

    }
}
